import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:formz/formz.dart';
import 'package:incidentmanager/common/data/repositories/case_repository.dart';
import 'package:incidentmanager/models/case_address.dart';
import 'package:incidentmanager/models/case_along.dart';
import 'package:incidentmanager/models/case_content.dart';
import 'package:incidentmanager/models/case_type.dart';
import 'package:meta/meta.dart';

part 'case_form_event.dart';
part 'case_form_state.dart';

class CaseFormBloc extends Bloc<CaseFormEvent, CaseFormState> {
  final CaseRepository _caseRepository;

  CaseFormBloc({@required CaseRepository caseRepository})
      : assert(caseRepository != null),
        _caseRepository = caseRepository,
        super(const CaseFormState());

  @override
  Stream<CaseFormState> mapEventToState(CaseFormEvent event) async* {
    if (event is CaseTypeChanged) {
      yield _mapTypeChangedToState(event, state);
    } else if (event is CaseContentChanged) {
      yield _mapContentChangedToState(event, state);
    } else if (event is CaseImagesChanged) {
      yield _mapImagesChangedToState(event, state);
    } else if (event is CaseAlongChanged) {
      yield _mapAlongChangedToState(event, state);
    } else if (event is CaseAddressChanged) {
      yield _mapAddressChangedToState(event, state);
    } else if (event is CaseSubmitted) {
      yield* _mapCaseSubmittedToState(event, state);
    }
  }

  /// 案件类型修改
  CaseFormState _mapTypeChangedToState(
      CaseTypeChanged event, CaseFormState state) {
    final caseType = CaseType.dirty(event.caseType);
    return state.copyWith(
      caseType: caseType,
      status: Formz.validate(
        [
          state.caseContent,
          state.caseAlong,
          state.caseAddress,
          caseType,
        ],
      ),
    );
  }

  /// 案件内容修改
  CaseFormState _mapContentChangedToState(
      CaseContentChanged event, CaseFormState state) {
    final caseContent = CaseContent.dirty(event.caseContent);
    return state.copyWith(
      caseContent: caseContent,
      status: Formz.validate(
        [
          state.caseType,
          state.caseAlong,
          state.caseAddress,
          caseContent,
        ],
      ),
    );
  }

  /// 案件图片修改
  CaseFormState _mapImagesChangedToState(
      CaseImagesChanged event, CaseFormState state) {
    return state.copyWith(
      caseImages: state.caseImages,
    );
  }

  /// 案件所属修改
  CaseFormState _mapAlongChangedToState(
      CaseAlongChanged event, CaseFormState state) {
    final caseAlong = CaseAlong.dirty(event.caseAlong);
    return state.copyWith(
      caseAlong: caseAlong,
      status: Formz.validate(
        [
          state.caseType,
          state.caseContent,
          state.caseAddress,
          caseAlong,
        ],
      ),
    );
  }

  /// 案件所属修改
  CaseFormState _mapAddressChangedToState(
      CaseAddressChanged event, CaseFormState state) {
    final caseAddress = CaseAddress.dirty(event.caseAddress);
    return state.copyWith(
      caseAddress: caseAddress,
      status: Formz.validate(
        [
          state.caseType,
          state.caseContent,
          state.caseAlong,
          caseAddress,
        ],
      ),
    );
  }

  /// 提交案件
  Stream<CaseFormState> _mapCaseSubmittedToState(
      CaseSubmitted event, CaseFormState state) async* {
    await _caseRepository.add(
        type: null, content: null, along: null, adress: null);
  }
}
